﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Web.Security;
using Common;
using Common.Extensions;
using log4net;
using LoveEat.Enum;
using LoveEat.Helper;
using LoveEat.MODEL.WeChat;
using LoveEat.WeChat;
using System.Configuration;

namespace LoveEat.WebController
{

    /// <summary>
    /// 微信接口事件
    /// </summary>
    public class LuckyMpController : BaseController
    {

        private readonly WxPublicFunc _wxPublicFunc = new WxPublicFunc();

        #region 微信接口


        /// <summary>
        /// 验证签名，检验是否是从微信服务器上发出的请求
        /// </summary>
        /// <param name="model">请求参数模型 Model</param>
        /// <returns>是否验证通过</returns>
        private bool CheckSignature(WeChatRequestModel model)
        {
            string Token = ConfigurationManager.AppSettings["_Token"];
            string signature, timestamp, nonce, tempStr;
            //获取请求来的参数
            signature = model.signature;
            timestamp = model.timestamp;
            nonce = model.nonce;
            //创建数组，将 Token, timestamp, nonce 三个参数加入数组
            string[] array = { Token, timestamp, nonce };
            //进行排序
            Array.Sort(array);
            //拼接为一个字符串
            tempStr = String.Join("", array);
            //对字符串进行 SHA1加密
            tempStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tempStr, "SHA1").ToLower();
            //判断signature 是否正确
            if (tempStr.Equals(signature))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 公众号接口
        /// </summary>
        /// <returns></returns>
        public ActionResult WxInterface()
        {
            Log.Info("WxInterface:go");
            Log.Info("WxInterface:" + Request.HttpMethod.ToLower());
            if (Request.HttpMethod.ToLower() == "get")
            {
                Log.Info("LuckyMpController | WxInterface CheckSignature 验证!!");
                WeChatRequestModel model = new WeChatRequestModel();
                model.signature = Request.QueryString["signature"];
                model.timestamp = Request.QueryString["timestamp"];
                model.nonce = Request.QueryString["nonce"];

                model.echostr = Request.QueryString["echostr"];

                //获取请求来的 echostr 参数
                string echoStr = model.echostr;
                //通过验证
                if (CheckSignature(model))
                {
                    if (!string.IsNullOrEmpty(echoStr))
                    {
                        //将随机生成的 echostr 参数 原样输出
                        //Response.Write(echoStr);
                        ////截止输出流
                        //Response.End();
                        Log.Info("LuckyMpController | WxInterface echoStr:" + echoStr);
                        return Content(echoStr);
                    }
                }
            }
            Log.Info("LuckyMpController | WxInterface Event Request " + Request.Url.AbsoluteUri);
            if (Request.Url == null)
            {
                return View();
            }
            //获取请求来的 echostr 参数
            try
            {
                Log.Info("LuckyMpController | WxInterface Event Request" + System.Web.HttpContext.Current.Request.InputStream);
                var s = System.Web.HttpContext.Current.Request.InputStream;
                if (s.Length <= 0)
                {
                    Log.Error("LuckyMpController | WxInterface : None inputstread ");
                    return View();
                }
                var b = new byte[s.Length];
                s.Read(b, 0, (int)s.Length);
                var strPostValue = Encoding.UTF8.GetString(b);
                Log.Info("LuckyMpController | ReceiveWxEventPost XMCONTENT - " + strPostValue);

                var strJson = JsonSerializerHelper.ConvertXmlToJson(strPostValue);
                strJson =
                    strJson.Replace("{\"xml\":", "")
                        .Replace("{\"#cdata-section\":", "")
                        .Replace("\"},", "\",")
                        .Replace("}}}", "}");
                var dictJsonData = JsonLib.DataRowFromJson(strJson);
                var strMsgType = dictJsonData["MsgType"].ToString();
                var strOriginalId = dictJsonData["ToUserName"].ToString();

                var wechatInfo = OperateContext.Current.BLLSession.Iwechat_infoBLL.GetListBy(w => w.originalId == strOriginalId).FirstOrDefault();
                if (wechatInfo == null || wechatInfo.id <= 0)
                {
                    Log.Info("LuckyMpController | ReceiveWxEventPost None WechatMp Info - " + strOriginalId);
                    return View();
                }
                var strRetContent = string.Empty;
                switch (strMsgType.ToLower())
                {
                    case "event":
                        var jsonModelEvent = JsonSerializerHelper.Deserialize<WechatEventHistory>(strJson);
                        jsonModelEvent.WechatInfoId = wechatInfo.id;
                        jsonModelEvent.EventContent = strJson;
                        //var wechatEventHistoryBll = new WechatEventHistoryBLL();
                        //wechatEventHistoryBll.Add(jsonModelEvent);

                        strRetContent = DealEvent(jsonModelEvent, wechatInfo);
                        break;
                    case "text":
                    case "image":
                    case "voice":
                    case "video":
                    case "shortvideo":
                    case "location":
                    case "link":
                        //var jsonModelMsg = JsonSerializerHelper.Deserialize<WeChatMsgRev>(strJson);
                        //jsonModelMsg.WechatInfoId = wechatInfo.Id;
                        //var wechatMsgRevBll = new WeChatMsgRevBLL();
                        //wechatMsgRevBll.Add(jsonModelMsg);
                        //strRetContent = DealMsg(jsonModelMsg, wechatInfo);
                        break;
                }

                Log.Info("LuckyMpController | WxInterface : Return message content - " + strRetContent);
                Response.ContentType = "text/xml";
                Response.Write(strRetContent);
            }
            catch (Exception ex)
            {
                Log.Error("LuckyMpController | WxInterface : Exception - " + ex.Message + ex.StackTrace);
            }

            return View();
        }

        /// <summary>
        /// 第三方登录验证接口
        /// </summary>
        /// <param name="callBackUrlEncode"></param>
        /// <param name="wechatInfoId"></param>
        /// <returns></returns>
        public ActionResult WxOAutherize(string callBackUrlEncode, int wechatInfoId)
        {
            if (Request.Url == null)
            {
                return View();
            }

            Log.Info("LuckyMpController | WxOAutherize Client Url " + Request.Url);

            Log.Info("LuckyMpController | WxOAutherize Client Parameter " + wechatInfoId + " - " + callBackUrlEncode);

            var wechatInfo = OperateContext.Current.BLLSession.Iwechat_infoBLL.GetListBy(w => w.id == wechatInfoId).FirstOrDefault();
            Log.Info("LuckyMpController | WxOAutherizewechatInfo" + wechatInfo.appId);
            Log.Info("LuckyMpController | WxOAutherize Request Url callBackUrlEncode " + Request.Url);

            var strRedirectUrl = System.Web.HttpContext.Current.Server.UrlEncode("http://" + Request.Url.Host + "/LuckyMp/WxAuthUserToken?authcallback=" + EncryptionLib.Encrypt(callBackUrlEncode));
            const string strWxUserAuthCodeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope=snsapi_userinfo&state={2}#wechat_redirect";

            if (wechatInfo != null)
            {
                var strAuthUrl = string.Format(strWxUserAuthCodeUrl, wechatInfo.appId, strRedirectUrl, wechatInfo.id);
                Log.Info("LuckyMpController | WxOAutherize Request Url " + strAuthUrl);
                Response.Redirect(strAuthUrl);
            }

            return View();
        }

        /// <summary>
        /// 微信登录验证回调接口，处理完毕并跳回验证前提供的回调地址
        /// </summary>
        /// <returns></returns>
        public ActionResult WxAuthUserToken()
        {
            Log.Info("LuckyMpController | WxAuthUserToken Request Url " + System.Web.HttpContext.Current.Request.Url.PathAndQuery);

            #region 校验
            if (Request.QueryString["state"] == null)
            {
                //回调参数不正确
                return View();
            }

            if (Request.QueryString["code"] == null || string.IsNullOrWhiteSpace(Request.QueryString["code"]))
            {
                //用户未授权
                return View();
            }

            if (Request.QueryString["state"] == null || string.IsNullOrWhiteSpace(Request.QueryString["state"]))
            {
                //没有state
                return View();
            }

            if (Request.QueryString["authcallback"] == null || string.IsNullOrWhiteSpace(Request.QueryString["authcallback"]))
            {
                //没有oauthcallback
                return View();
            }
            #endregion

            var strWxUserAuthCode = Request.QueryString["code"];
            var strOAuthCallBack = EncryptionLib.Decrypt(Request.QueryString["authcallback"]).Replace("\0", "");
            if (string.IsNullOrWhiteSpace(strOAuthCallBack))
                return View();

            try
            {
                var strWechatInfoId = Request.QueryString["state"];
                int wechatInfoId = int.Parse(strWechatInfoId);
                var wechatInfo = OperateContext.Current.BLLSession.Iwechat_infoBLL.GetListBy(w => w.id == wechatInfoId).FirstOrDefault();
               
                if (wechatInfo != null)
                {
                    var oauthUser = _wxPublicFunc.GetWebAuthTokenUserInfo(wechatInfo.appId, wechatInfo.secret, strWxUserAuthCode);
                    if (oauthUser == null || string.IsNullOrWhiteSpace(oauthUser.openid))
                    {
                        Log.Info("LuckyMpController | WxAuthUserToken oauthUser Info : Cannot get the open id: " + System.Web.HttpContext.Current.Request.Url.PathAndQuery);
                        return View();
                    }

                    var wechatUserInfo =
                        OperateContext.Current.BLLSession.Iwechat_userBLL.GetListBy(
                            w => w.OpenId == oauthUser.openid && w.WeChatInfoId == wechatInfo.id).FirstOrDefault();
                    if (wechatUserInfo != null && wechatUserInfo.UserId > 0)
                    {
                        wechatUserInfo.NickName = oauthUser.nickname;
                        wechatUserInfo.Sex = oauthUser.sex;
                        wechatUserInfo.Province = oauthUser.province;
                        wechatUserInfo.City = oauthUser.city;
                        wechatUserInfo.Country = oauthUser.country;
                        wechatUserInfo.Headimgurl = oauthUser.headimgurl;
                        wechatUserInfo.Unionid = oauthUser.unionid;
                        wechatUserInfo.WeChatInfoId = wechatInfo.id;
                        wechatUserInfo.ActiveStatus = 1;
                        wechatUserInfo.Subscribe = oauthUser.subscribe;
                        wechatUserInfo.SubscribeTime = oauthUser.subscribe == 1
                            ? (DateTime)_wxPublicFunc.FormatToTime(oauthUser.subscribe_time.ToString())
                            : Convert.ToDateTime("1900-01-01");
                        wechatUserInfo.updateTime = DateTime.Now;
                        wechatUserInfo.createTime = DateTime.Now;
                        OperateContext.Current.BLLSession.Iwechat_userBLL.Update(wechatUserInfo);
                    }
                    else
                    {

                        Log.Info("LuckyMpController | WxAuthUserToken wechatUserInfo");
                        wechatUserInfo = new MODEL.wechat_user
                        {
                            OpenId = oauthUser.openid,
                            NickName = oauthUser.nickname,
                            Sex = oauthUser.sex,
                            Province = oauthUser.province,
                            City = oauthUser.city,
                            Country = oauthUser.country,
                            Headimgurl = oauthUser.headimgurl,
                            Unionid = oauthUser.unionid,
                            WeChatInfoId = wechatInfo.id,
                            Subscribe = oauthUser.subscribe,
                            SubscribeTime = oauthUser.subscribe == 1
                                ? (DateTime)_wxPublicFunc.FormatToTime(oauthUser.subscribe_time.ToString())
                                : Convert.ToDateTime("1900-01-01"),
                            createTime=DateTime.Now,
                            ActiveStatus = 1
                        };
                        OperateContext.Current.BLLSession.Iwechat_userBLL.Add(wechatUserInfo);

                    }

                    if (oauthUser.subscribe == 1)
                    {
                        var paramUserInfo =
                            OperateContext.Current.BLLSession.Iwechat_param_userBLL.GetListBy(
                                w => w.OpenId == oauthUser.openid && w.WeChatInfoId == wechatInfo.id).FirstOrDefault();
                        if (paramUserInfo != null && paramUserInfo.ParamUserId > 0)
                        {
                            paramUserInfo.NickName = oauthUser.nickname;
                            paramUserInfo.Sex = oauthUser.sex;
                            paramUserInfo.Province = oauthUser.province;
                            paramUserInfo.City = oauthUser.city;
                            paramUserInfo.Country = oauthUser.country;
                            paramUserInfo.Headimgurl = oauthUser.headimgurl;
                            paramUserInfo.Unionid = oauthUser.unionid;
                            paramUserInfo.SubscribeTime = _wxPublicFunc.FormatToTime(oauthUser.subscribe_time.ToString());
                            paramUserInfo.Remark = oauthUser.remark;
                            paramUserInfo.GroupId = oauthUser.groupid;
                            paramUserInfo.Subscribe = oauthUser.subscribe;
                            OperateContext.Current.BLLSession.Iwechat_param_userBLL.Update(paramUserInfo);
                        }
                    }

                    var strUserInfo = "OPENID:" + oauthUser.openid + "<br>nickname:" + oauthUser.nickname +
                                      "<br>sex:" + oauthUser.sex + "<br>province:" + oauthUser.province + "<br>city:" +
                                      oauthUser.city + "<br>country:" + oauthUser.country + "<br>headimgurl:" +
                                      oauthUser.headimgurl + ",subscribe" + oauthUser.subscribe;
                    Log.Info("LuckyMpController | WxAuthUserToken oauthUser Info " + strUserInfo);

                    var strUserInfoBase64 = StringExtension.ToBase64String(
                        System.Web.HttpContext.Current.Server.UrlEncode(JsonSerializerHelper.Serialize(oauthUser)));

                    var strRedirectUrl = strOAuthCallBack +
                                         (strOAuthCallBack.IndexOf("?", StringComparison.Ordinal) > 0 ? "&" : "?") +
                                         "openid=" + oauthUser.openid + "&userInfo=" + strUserInfoBase64;
                    Log.Info("LuckyMpController | WxAuthUserToken oauthUser Info " + strRedirectUrl);
                    Response.Redirect(strRedirectUrl);
                }
                return View();
            }
            catch (WxErrorMsgException ex)
            {
                Log.Error(ex.ToString());
                ViewBag.UserInfo = ex.ToString();
            }
            catch (Exception ex)
            {
                Log.Error(ex.ToString() + ex.StackTrace);
                ViewBag.UserInfo = ex.ToString();
            }
            return View();
        }



        #endregion



        #region 处理接收事件
        /// <summary>
        /// 处理接收事件
        /// </summary>
        /// <param name="weChatEventRev"></param>
        /// <param name="wechatInfo"></param>
        /// <returns></returns>
        private string DealEvent(WechatEventHistory weChatEventRev, MODEL.wechat_info wechatInfo)
        {
            Log.Info("LuckyMpController | DealEvent Begin - " + weChatEventRev.Event);

            var strRetContent = string.Empty;

            switch (weChatEventRev.Event.ToLower())
            {
                case "subscribe": //关注
                    strRetContent = DealParamQrCodeToSubcribeUser(weChatEventRev, wechatInfo, (int)ScanSource.RedEnvelopeCode);
                    break;
                case "unsubscribe": //取消订阅
                    UnsubscribeUser(weChatEventRev, wechatInfo);
                    break;
                case "scan": //用户已关注时的事件推送
                    if (!string.IsNullOrWhiteSpace(weChatEventRev.EventKey) &&
                        !string.IsNullOrWhiteSpace(weChatEventRev.Ticket))
                    {
                        // strRetContent = DealParamQrCodeToSubcribeUser(weChatEventRev, wechatInfo, (int)ScanSource.ScanParamCode);
                    }
                    break;
                case "location": //上报地理位置事件
                    break;
                case "click": //自定义菜单事件
                    break;
                case "view": //点击菜单跳转链接时的事件推送
                    break;
                case "card_pass_check"://卡券通过审核
                case "card_not_pass_check"://卡券未通过审核
                case "user_get_card"://用户领取卡券
                case "user_del_card"://用户删除卡券
                case "user_consume_card"://核销事件
                case "User_pay_from_pay_cell"://微信买单事件
                case "user_view_card": //进入会员卡事件推送
                case "user_enter_session_from_card"://用户从卡券进入公众号会话
                case "card_pay_order": //券点流水详情事件(朋友的券)
                    //var luckMpCard = new LuckMpCard();
                    //luckMpCard.WxCardEventProccess(weChatEventRev, wechatInfo);
                    break;
                case "masssendjobfinish": //群发事件推送群发结果
                    break;
                default:
                    strRetContent = string.Empty;
                    break;
            }

            return strRetContent;
        }



        #endregion

        #region 处理扫描带参数二维码的关注事件并推送文章
        /// <summary>
        /// 处理扫描带参数二维码的关注事件并推送文章
        /// </summary>
        private string DealParamQrCodeToSubcribeUser(WechatEventHistory weChatMsgRev, MODEL.wechat_info wechatInfo, int scanSource)
        {
            var strRetContent = "非常感谢关注" + wechatInfo.weChatName;
            Log.Info("LuckyMpController | DealParamQrCodeToSubcribeUser Begin - " + weChatMsgRev.FromUserName);

            try
            {

                var accessToken = _wxPublicFunc.GetWxToken(wechatInfo.appId, wechatInfo.secret);
                var wxUserInfo = new WxUserInfo();
                if (!string.IsNullOrWhiteSpace(accessToken))
                {
                    wxUserInfo = _wxPublicFunc.GetUserInfoIncludeUnion(wechatInfo.appId, accessToken, weChatMsgRev.FromUserName, wechatInfo.secret);
                }
                Log.Info("LuckyMpController | DealParamQrCodeToSubcribeUser : accessToken - " + accessToken);
                if (wxUserInfo == null || wxUserInfo.subscribe != 1 || string.IsNullOrWhiteSpace(wxUserInfo.openid))
                {
                    Log.Info("LuckyMpController | DealParamQrCodeToSubcribeUser : Cannot get wechat user info by UnionWay - " + weChatMsgRev.FromUserName);
                    return _wxPublicFunc.SendWxTxt(wechatInfo, weChatMsgRev.FromUserName, strRetContent);
                }

                var paramUserInfo =
                    OperateContext.Current.BLLSession.Iwechat_param_userBLL.GetListBy(
                        s => s.OpenId == weChatMsgRev.FromUserName && s.WeChatInfoId == wechatInfo.id).FirstOrDefault();
                var wechatUserInfo = OperateContext.Current.BLLSession.Iwechat_userBLL.GetListBy(
                        s => s.OpenId == weChatMsgRev.FromUserName && s.WeChatInfoId == wechatInfo.id).FirstOrDefault();

                #region 单独处理关注标识字段
                if (paramUserInfo != null && paramUserInfo.ParamUserId > 0 && wxUserInfo.subscribe == 1)
                {
                    paramUserInfo.NickName = wxUserInfo.nickname;
                    paramUserInfo.Sex = wxUserInfo.sex;
                    paramUserInfo.Province = wxUserInfo.province;
                    paramUserInfo.City = wxUserInfo.city;
                    paramUserInfo.Country = wxUserInfo.country;
                    paramUserInfo.Headimgurl = wxUserInfo.headimgurl;
                    paramUserInfo.Unionid = wxUserInfo.unionid;
                    paramUserInfo.SubscribeTime = _wxPublicFunc.FormatToTime(wxUserInfo.subscribe_time.ToString());
                    paramUserInfo.Remark = wxUserInfo.remark;
                    paramUserInfo.GroupId = wxUserInfo.groupid;
                    paramUserInfo.Subscribe = wxUserInfo.subscribe;
                    OperateContext.Current.BLLSession.Iwechat_param_userBLL.Update(paramUserInfo);
                }

                if (wechatUserInfo != null && wechatUserInfo.UserId > 0 && wxUserInfo.subscribe == 1)
                {
                    wechatUserInfo.NickName = wxUserInfo.nickname;
                    wechatUserInfo.Sex = wxUserInfo.sex;
                    wechatUserInfo.Province = wxUserInfo.province;
                    wechatUserInfo.City = wxUserInfo.city;
                    wechatUserInfo.Country = wxUserInfo.country;
                    wechatUserInfo.Headimgurl = wxUserInfo.headimgurl;
                    wechatUserInfo.Unionid = wxUserInfo.unionid;
                    wechatUserInfo.SubscribeTime = _wxPublicFunc.FormatToTime(wxUserInfo.subscribe_time.ToString());
                    wechatUserInfo.Remark = wxUserInfo.remark;
                    wechatUserInfo.GroupId = wxUserInfo.groupid;
                    wechatUserInfo.Subscribe = wxUserInfo.subscribe;

                    OperateContext.Current.BLLSession.Iwechat_userBLL.Update(wechatUserInfo);
                }
                #endregion

                //var wechatParamQrCodeBll = new WechatParamQrCodeBLL();
                //var qrCodeModel = wechatParamQrCodeBll.GetModelByTicket(weChatMsgRev.Ticket);

               // var isParamUser = false;
                //if (qrCodeModel != null && qrCodeModel.QrCodeId > 0 && qrCodeModel.WechatInfoId == wechatInfo.id)
                //{

                //    //strRetContent = SendBindUserArticle(qrCodeModel, wechatInfo, wxUserInfo, paramUserInfo, wechatUserInfo, out isParamUser);
                //    //if (string.IsNullOrWhiteSpace(strRetContent))
                //    //{
                //    //    strRetContent = _wxPublicFunc.SendWxTxt(wechatInfo, weChatMsgRev.FromUserName, strRetContent);
                //    //}
                //}
                //else
                //{
                //    //非带参数二维码扫描关注事件

                //   // return SendUserArticleFromNomalSubscribe(wechatInfo, wxUserInfo);

                //}

                //var scanEvent = new ScanEvent
                //{
                //    ScanDate = DateTime.Now,
                //    WechantInfoId = wechatInfo.id,
                //    OpenId = weChatMsgRev.FromUserName,
                //    IsPramaUser = isParamUser,
                //    ScanQrContent = qrCodeModel.QrCodeContent,
                //    ScanSource = scanSource,
                //    MerchantId = qrCodeModel.MerchantId,
                //    ActivityId = 0
                //};

                //var scanEventBll = new ScanEventBLL();
                //scanEventBll.Add(scanEvent);
             
                Log.Info("LuckyMpController | BindParamQrCodeToSubcribeUser : SendWxTxt - " + strRetContent);
                strRetContent = _wxPublicFunc.SendWxTxt(wechatInfo, weChatMsgRev.FromUserName, "");
            }
            catch (Exception ex)
            {
                Log.Error("LuckyMpController | BindParamQrCodeToSubcribeUser : Exception - " + ex.Message + ex.StackTrace);
                strRetContent = _wxPublicFunc.SendWxTxt(wechatInfo, weChatMsgRev.FromUserName, strRetContent);
            }
            return strRetContent;
        }
        #endregion

        #region 处理取消关注
        /// <summary>
        /// 处理取消关注
        /// </summary>
        private void UnsubscribeUser(WechatEventHistory weChatMsgRev, MODEL.wechat_info wechatInfo)
        {
            var userOpenId = weChatMsgRev.FromUserName;
            var paramUser = OperateContext.Current.BLLSession.Iwechat_param_userBLL.GetListBy(s => s.OpenId == userOpenId && s.WeChatInfoId == wechatInfo.id).FirstOrDefault();
            if (paramUser != null && paramUser.ParamUserId > 0)
            {
                paramUser.Subscribe = 0;
                paramUser.UnSubscribeTime = DateTime.Now;
                OperateContext.Current.BLLSession.Iwechat_param_userBLL.Update(paramUser);
            }
            var wechatUser = OperateContext.Current.BLLSession.Iwechat_userBLL.GetListBy(s => s.OpenId == userOpenId && s.WeChatInfoId == wechatInfo.id).FirstOrDefault();
            if (wechatUser != null && wechatUser.UserId > 0)
            {
                wechatUser.Subscribe = 0;
                wechatUser.UnSubscribeTime = DateTime.Now;
                OperateContext.Current.BLLSession.Iwechat_userBLL.Update(wechatUser);

            }
        }
        #endregion

        public ActionResult test()
        {

            Log.Info("ddddddddddddddd");

            return View();
        }
    }



}
